﻿using System.Collections.Generic;
using Spring.Objects.Factory;
using System;

namespace Domain.Repository.Impl
{
    public class SimpleQueryCacheService :AbstractBaseLogger, IQueryCacheService, IInitializingObject
    {
        protected static IDictionary<string, object> dictInstances;
        protected const string separator = ".";

        protected string BuildDictKey(object mainkey, QueryParameters parameters)
        {
            if (null == mainkey || String.IsNullOrWhiteSpace(mainkey.ToString()))
            {
                return null;
            }

            string subkey = null;
            if (null != parameters && parameters.Parameters.Count > 0)
            {
                foreach (QueryParameter entry in parameters.Parameters)
                {
                    if (QueryParameters.STR_StartNumber.Equals(entry.Name)&&Convert.ToInt64(entry.Value)>1)
                    {
                        return null;
                    }
                    subkey += entry.Name;
                    subkey += Convert.ToString(entry.Value);
                }
            }

            subkey = String.IsNullOrWhiteSpace(subkey) ? null : CommonTools.UniqueIDFromString(subkey);
            string sqlkey = mainkey.ToString().StartsWith("select ", StringComparison.OrdinalIgnoreCase)
                ? CommonTools.UniqueIDFromString(mainkey.ToString().Trim()) : mainkey.ToString().Trim();
            return null == subkey ? sqlkey : sqlkey + separator + subkey;
        }

        public T Get<T>(object cacheKey) where T : class
        {
            return Get<T>(cacheKey, null);
        }

        public T Get<T>(object key, QueryParameters parameters) where T : class
        {
            var cachekey = BuildDictKey(key, parameters);
            if (String.IsNullOrWhiteSpace(cachekey) || !ContainsKey(cachekey))
            {
                return null;
            }
            logger.Info("Find cache instance by key [" + cachekey + "] : " + dictInstances[cachekey]);
            return dictInstances[cachekey] as T;
        }

        public void Add<T>(object key, T instance) where T : class
        {
            Add<T>(key, null, instance);
        }

        public void Add<T>(object key, QueryParameters parameters, T instance) where T : class
        {
            var cachekey = BuildDictKey(key, parameters);
   
            if (null == instance)
            {
                logger.Warn("Cache instance must be not null, cache key : " + cachekey);
                return;
            }
            if (String.IsNullOrWhiteSpace(cachekey) || ContainsKey(cachekey))
            {
                return;
            }
            logger.Info("Add cache key string : " + cachekey);
            dictInstances.Add(cachekey, instance);
        }

        public void AfterPropertiesSet()
        {
            if (null != dictInstances)
            {
                dictInstances.Clear();
            }
            else
            {
                dictInstances = new Dictionary<string, object>();
            }
        }


        public void Clear()
        {
            lock (this)
            {
                dictInstances.Clear();
            }
        }

        public bool Contains(object key)
        {
            return ContainsKey(BuildDictKey(key, null));
        }

        public bool Contains(object key, QueryParameters parameters)
        {
            return ContainsKey(BuildDictKey(key, parameters));
        }

        protected bool ContainsKey(string dictkey)
        {
            return String.IsNullOrWhiteSpace(dictkey) ? false : dictInstances.ContainsKey(dictkey);
        }
    }
}
